package com.sxds.wn.service;

import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;

import org.apache.commons.lang.exception.ExceptionUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.sxds.wn.exception.DataAccessException;
import com.sxds.wn.exception.ParameterException;
import com.sxds.wn.exception.ServiceException;
import com.sxds.wn.security.dto.User;
import com.sxds.wn.util.ReflectUtil;

/**
 * Description: <p>陕西省地税渭南-餐饮业定税系统</p>
 * Content Desc:<p><p>
 * Copy Right of Personal Tangtao 2007-2020
 * @author Andy
 * @version 1.0
 */
public abstract class BaseService implements IService {
	
	//日志记录对象
	protected Log logger = LogFactory.getLog(getClass());
	//请求对象
	protected Request request;
	//处理返回对象
	protected Response response;
	//用户对象
	protected User user = null;
	//服务处理方法
	protected String processServiceMethod;
	
	/* (non-Javadoc)
	 * @see com.andy.service.IService#process(com.andy.service.Request)
	 */
	public Response process(Request request) throws ServiceException {
		this.request = request;
		processServiceMethod = this.request.getHttpRequest().getParameter(REQUEST_PROCESS_SERVICE_METHOD);
		if( processServiceMethod!=null ) this.request.setProcessServiceMethod(processServiceMethod);
		try{
			//检查业务参数
			this.validateParameters();
			//检查权限
			this.checkPermission();
			//初始化返回的对象
			this.init();
			//具体业务处理
			this.service();
		}catch(SecurityException ex){
			//处理权限异常
			logger.error("权限异常",ex);
			this.processException(ex);
			this.request.getHttpRequest().setAttribute("exception", ex);
			throw new ServiceException("权限异常："+ex);
		}catch(ParameterException ex){
			//处理参数错误异常
			logger.error("提交参数错误",ex);
			this.processException(ex);
			this.request.getHttpRequest().setAttribute("exception", ex);
			throw new ServiceException("提交参数错误："+ex);
		}catch(DataAccessException ex){
			//处理数据访问层异常
			logger.error("访问数据错误",ex);
			this.processException(ex);
			this.request.getHttpRequest().setAttribute("exception", ex);
			throw new ServiceException("访问数据错误："+ex);
		}finally{
			//处理最终返回信息
		}
		return this.response;
	}

	/**
	 * 初始化必要的参数内容
	 */
	public void init(){
		//this.springContext = WebApplicationContextUtils.getRequiredWebApplicationContext(request.getHttpRequest());
		this.response = new Response();
		this.response.setPageAttributes(new HashMap());
		this.user = (User)this.request.getHttpRequest().getSession().getAttribute(USER_SESSION_KEY);
	}
	
	/**
	 * 对Web页面请求进行解析，产生需要的对象
	 * @param className 解析转换后的ClassName
	 * @return java.lang.Object
	 * @throws DataAccessException 数据访问异常
	 */
	protected Object parseRequest(String className) throws DataAccessException {
		Object bean = null;
		try{
			bean = ReflectUtil.getObject(this.request.getHttpRequest(), className);
		}catch(Exception ex){
			throw new DataAccessException(ex);
		}
		return bean;
	}
	
	/**
	 * 检查用户是否存在访问权限，子类必须实现
	 * @return true--通过验证,false--无权限访问
	 * @throws SecurityException
	 */
	protected abstract boolean checkPermission() throws SecurityException;
	
	/**
	 * 检查提交参数是否正确，子类必须实现
	 * @return true--正确,false--参数错误
	 * @throws ParameterException
	 */
	protected abstract boolean validateParameters() throws ParameterException;

	/**
	 * 处理调用数据库访问层抛出异常信息
	 * @param ex
	 */
	private void processException(Exception ex){
		this.response.setOk(false);
		this.response.setResponseMessage("发生错误，错误信息：" + ExceptionUtils.getStackTrace(ex));
	}
	
	/**
	 * 具体业务处理接口，子类必须实现
	 * @throws ServiceException
	 */
	public void service() throws DataAccessException{
		try{
			ReflectUtil.invokeMethod(this, this.request.getProcessServiceMethod(), new Object[]{});
		}catch(Exception ex){
			this.logger.error("Invoke service method error",ex);
			this.response.setOk(false);
			this.response.setStackTraceException(ex);
			if( ex instanceof InvocationTargetException){
				Throwable targetEx = ((InvocationTargetException)ex).getTargetException();
				if( targetEx!=null ) this.response.setResponseMessage("请求错误：" + targetEx.getMessage());
			}else{
				this.response.setResponseMessage("请求错误：" + ex.getMessage());
			}
		}
	}

}
